/*
 * Copyright (C) 2007 Luca Veltri - University of Parma - Italy
 *
 * This file is part of MjSip (http://www.mjsip.org)
 *
 * MjSip is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * MjSip is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MjSip; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author(s):
 * Luca Veltri (luca.veltri@unipr.it)
 */

package org.zoolu.net;



import java.io.*;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.spec.PKCS8EncodedKeySpec;
import org.zoolu.tools.Base64;



/** Key management tool.
 */
public class TlsTool
{

    /** Begin private key */
    static final String BEGIN_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----";

    /** End private key */
    static final String END_PRIVATE_KEY="-----END PRIVATE KEY-----";



    /** Imports a private key. */
    public static Key importPrivateKey(String file_name) throws Exception
    {  InputStream is=new FileInputStream(file_name);
        Key key=importPrivateKey(is);
        is.close();
        return key;
    }


    /** Imports a private key. */
    public static Key importPrivateKey(InputStream is) throws Exception
    {  byte[] buff=new byte[is.available()];
        is.read(buff);
        PKCS8EncodedKeySpec pkcs8_eks=new PKCS8EncodedKeySpec(buff);
        KeyFactory kf=KeyFactory.getInstance("RSA");
        return kf.generatePrivate(pkcs8_eks);
    }


    /** Imports a private key from base64 format. */
    public static Key importPrivateKeyBASE64(String file_name) throws Exception
    {  BufferedReader rr=new BufferedReader(new FileReader(file_name));
        Key key=importPrivateKeyBASE64(rr);
        rr.close();
        return key;
    }

    /** Imports a private key from base64 format. */
    public static Key importPrivateKeyBASE64(BufferedReader rr) throws Exception
    {  String buff="";
        for (String line=rr.readLine(); line!=null; line=rr.readLine())
        {  buff+=line;
        }
        int begin=buff.indexOf(BEGIN_PRIVATE_KEY);
        if (begin>=0) begin+=BEGIN_PRIVATE_KEY.length(); //else begin=0;
        int end=buff.indexOf(END_PRIVATE_KEY);
        //if (end<0) end=buff.length();
        String encoded=buff.substring(begin,end);
        //BASE64Decoder decoder=new BASE64Decoder();
        //PKCS8EncodedKeySpec pkcs8_eks=new PKCS8EncodedKeySpec(decoder.decodeBuffer(encoded));
        PKCS8EncodedKeySpec pkcs8_eks=new PKCS8EncodedKeySpec(Base64.decode(encoded));
        KeyFactory kf=KeyFactory.getInstance("RSA");
        return kf.generatePrivate(pkcs8_eks);
    }


    /** Exports a private key. */
    public static void exportPrivateKey(Key key, String file_name) throws IOException
    {  OutputStream os=new FileOutputStream(file_name);
        exportPrivateKey(key,os);
        os.close();
    }


    /** Exports a private key. */
    public static void exportPrivateKey(Key key, OutputStream os) throws IOException
    {  os.write(key.getEncoded());
    }


    /** Exports a private key in base64 format. */
    public static void exportPrivateKeyBASE64(Key key, String file_name) throws Exception
    {  FileWriter file=new FileWriter(file_name);
        exportPrivateKeyBASE64(key,file);
        file.close();
    }


    /** Exports a private key in base64 format. */
    public static void exportPrivateKeyBASE64(Key key, Writer wr) throws Exception
    {  //BASE64Encoder encoder=new BASE64Encoder();
        //String encoded=encoder.encode(key.getEncoded());
        String encoded=Base64.encode(key.getEncoded());
        wr.write(BEGIN_PRIVATE_KEY+"\r\n");
        wr.write(encoded);
        wr.write("\r\n"+END_PRIVATE_KEY);
    }


    /** Main method. */
    public static void main(String[] args)
    {  String store_file=null;
        char[] passwd=null;
        String alias=null;
        String key_file="key.pem";
        for (int i=0; i<args.length; i++)
        {  if (args[i].equals("-keystore"))
        {  store_file=args[++i];
        }
        else
        if (args[i].equals("-storepass"))
        {  passwd=args[++i].toCharArray();
        }
        else
        if (args[i].equals("-alias"))
        {  alias=args[++i];
        }
        else
        if (args[i].equals("-file"))
        {  key_file=args[++i];
        }
        }
        if (store_file==null || passwd==null || alias==null)
        {  System.out.println("usage:\n\n   java TlsTool -keystore <store_file> -storepass <passwd> -alias <alias> [-file <key_file>]");
            System.exit(0);
        }
        // else
        try
        {  KeyStore ks=KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(new FileInputStream(store_file),passwd); // here passwd is used only for integrity check
            //System.out.print("TlsTool: current cert aliases:");
            //for (java.util.Enumeration e=ks.aliases(); e.hasMoreElements(); ) System.out.print(" "+(String)e.nextElement());
            //System.out.println(" ");
            Key key=ks.getKey(alias,passwd);
            exportPrivateKeyBASE64(key,key_file);
            System.out.println("Private key stored in file <"+key_file+">");
        }
        catch (Exception e)
        {  e.printStackTrace();
        }
    }

}
